package com.define.commons.common.base;

import com.define.commons.common.utils.IPUtils;
import com.define.commons.common.utils.RS;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 全局捕捉异常Controller
 * @Author xiewenlong
 * @Date 2018/11/9 15:34
 */
@Slf4j
@RestControllerAdvice
public class ExceptionHandlerController {

    @Autowired
    protected HttpServletRequest request;

    /**
     * Catch Global Exception
     */
    @ExceptionHandler(Exception.class)
    public RS<Exception> handleExceptions(final Exception e, final WebRequest req) {
        recordErrorLog(request, e);
        return new RS(e);
    }

    /**
     * Record Error Log
     */
    public void recordErrorLog(HttpServletRequest request, Exception e){
        log.error("IP: {}, URI: {}, Method: {}, Param: {}, ErrorStackTrace: {}",
                IPUtils.getIpAddr(request),
                request.getRequestURI(),
                request.getMethod(),
                getParameterString(request),
                getExceptionTrace(e));
    }

    /**
     * Request ParameterMap Cast String
     */
    public String getParameterString(@NotNull HttpServletRequest request){
        Map.Entry entry;
        String name="", value = "";
        Map returnMap = new HashMap();
        Map map = request.getParameterMap();
        Iterator entries = map.entrySet().iterator();
        while (entries.hasNext()) {
            entry = (Map.Entry) entries.next();
            name = (String) entry.getKey();
            Object valueObj = entry.getValue();
            if(null == valueObj){
                value = "";
            }else if(valueObj instanceof String[]){
                String[] values = (String[])valueObj;
                for(int i=0; i<values.length; i++){
                    value = values[i] + ",";
                }
                value = value.substring(0, value.length()-1);
            }else{
                value = valueObj.toString();
            }
            returnMap.put(name, value);
        }
        return returnMap.toString();
    }

    /**
     * Get ExceptionTrace Info
     */
    public static String getExceptionTrace(Throwable e){
        if(e == null) {return null;}
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
        return sw.toString();
    }

}
